import heapq
import json
import sys
import random
import math
from typing import List, Tuple, Dict

# 尝试导入pygame，如果没有安装则提示
try:
    import pygame
    PYGAME_AVAILABLE = True
except ImportError:
    PYGAME_AVAILABLE = False
    print("注意：pygame未安装，只能使用控制台模式。安装pygame来启用可视化：pip install pygame")

def boss_battle_optimization(data: Dict) -> Dict:
    """
    使用分支限界法优化BOSS战策略
    
    Args:
        data: 包含BOSS血量和玩家技能的字典
    
    Returns:
        包含最小回合数和动作序列的字典
    """
    bosses = data["B"]
    skills = data["PlayerSkills"]
    
    def heuristic(boss_idx: int, boss_hp: int) -> int:
        """
        启发函数：估算击败剩余BOSS所需的最少回合数
        使用最高伤害技能进行乐观估计
        """
        if boss_idx >= len(bosses):
            return 0
        
        # 计算剩余总血量
        total_remaining_hp = boss_hp
        for i in range(boss_idx + 1, len(bosses)):
            total_remaining_hp += bosses[i]
        
        # 使用最高伤害进行乐观估计
        max_damage = max(skill[0] for skill in skills)
        return (total_remaining_hp + max_damage - 1) // max_damage
    
    # 优先队列：(f值, 已用回合数, 当前boss索引, 当前boss血量, 技能冷却状态, 动作序列)
    initial_cooldowns = [0] * len(skills)  # 初始所有技能都可用
    initial_f = heuristic(0, bosses[0])
    pq = [(initial_f, 0, 0, bosses[0], initial_cooldowns, [])]
    
    best_turns = float('inf')
    best_actions = []
    
    # 使用字典存储访问过的状态，记录到达该状态的最少回合数
    visited = {}
    
    while pq:
        f_val, turns, boss_idx, boss_hp, cooldowns, actions = heapq.heappop(pq)
        
        # 剪枝：如果当前回合数已经不优于最优解
        if turns >= best_turns:
            continue
        
        # 检查是否所有BOSS都被击败
        if boss_idx >= len(bosses):
            if turns < best_turns:
                best_turns = turns
                best_actions = actions[:]
            continue
        
        # 状态去重：如果已经用更少回合到达过相同状态，跳过
        state_key = (boss_idx, boss_hp, tuple(cooldowns))
        if state_key in visited and visited[state_key] <= turns:
            continue
        visited[state_key] = turns
        
        # 尝试使用每个技能
        for skill_idx, (damage, cooldown_time) in enumerate(skills):
            # 检查技能是否可用
            if cooldowns[skill_idx] > 0:
                continue
            
            # 构造新状态
            new_actions = actions + [skill_idx]
            new_turns = turns + 1
            
            # 更新冷却状态：所有技能冷却时间-1，使用的技能设置冷却时间
            new_cooldowns = [max(0, cd - 1) for cd in cooldowns]
            new_cooldowns[skill_idx] = cooldown_time
            
            # 更新BOSS状态
            new_boss_hp = boss_hp - damage
            new_boss_idx = boss_idx
            
            # 如果当前BOSS被击败，切换到下一个BOSS
            if new_boss_hp <= 0:
                new_boss_idx += 1
                if new_boss_idx < len(bosses):
                    new_boss_hp = bosses[new_boss_idx]
            
            # 计算新的f值进行剪枝
            h_val = heuristic(new_boss_idx, new_boss_hp)
            new_f_val = new_turns + h_val
            
            # 如果估算总回合数不优于当前最优解，剪枝
            if new_f_val >= best_turns:
                continue
            
            # 加入优先队列
            new_state = (new_f_val, new_turns, new_boss_idx, new_boss_hp, new_cooldowns, new_actions)
            heapq.heappush(pq, new_state)
    
    return {"min_turns": best_turns, "actions": best_actions}

# ===== 可视化相关代码 =====
if PYGAME_AVAILABLE:
    # 初始化pygame
    pygame.init()

    # 屏幕设置
    SCREEN_WIDTH = 1200
    SCREEN_HEIGHT = 800

    # 颜色定义
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    RED = (255, 0, 0)
    GREEN = (0, 255, 0)
    BLUE = (0, 0, 255)
    YELLOW = (255, 255, 0)
    PURPLE = (128, 0, 128)
    ORANGE = (255, 165, 0)
    GRAY = (128, 128, 128)
    DARK_GRAY = (64, 64, 64)
    LIGHT_BLUE = (173, 216, 230)
    GOLD = (255, 215, 0)

    # 字体设置 - 尝试使用系统中文字体
    try:
        # 尝试使用系统字体
        font_large = pygame.font.SysFont("microsoftyaheimicrosoftyaheiui", 48)
        font_medium = pygame.font.SysFont("microsoftyaheimicrosoftyaheiui", 36)
        font_small = pygame.font.SysFont("microsoftyaheimicrosoftyaheiui", 24)
    except:
        try:
            # 备选：使用其他中文字体
            font_large = pygame.font.SysFont("simhei", 48)
            font_medium = pygame.font.SysFont("simhei", 36)
            font_small = pygame.font.SysFont("simhei", 24)
        except:
            # 最后备选：使用默认字体，界面改为英文
            font_large = pygame.font.Font(None, 48)
            font_medium = pygame.font.Font(None, 36)
            font_small = pygame.font.Font(None, 24)
            print("Warning: Chinese font not available, using English interface")

    class Particle:
        """粒子特效类"""
        def __init__(self, x, y, color, velocity, life_time):
            self.x = x
            self.y = y
            self.color = color
            self.velocity = velocity
            self.life_time = life_time
            self.max_life = life_time
            
        def update(self):
            self.x += self.velocity[0]
            self.y += self.velocity[1]
            self.life_time -= 1
            
        def draw(self, screen):
            if self.life_time > 0:
                pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), 3)

    class SkillEffect:
        """技能特效类"""
        def __init__(self, start_pos, end_pos, skill_type, damage):
            self.start_pos = start_pos
            self.end_pos = end_pos
            self.skill_type = skill_type
            self.damage = damage
            self.progress = 0.0
            self.particles = []
            self.finished = False
            
        def update(self):
            if not self.finished:
                self.progress += 0.05
                
                # 计算当前位置
                current_x = self.start_pos[0] + (self.end_pos[0] - self.start_pos[0]) * self.progress
                current_y = self.start_pos[1] + (self.end_pos[1] - self.start_pos[1]) * self.progress
                
                # 根据技能类型添加粒子
                if self.skill_type == 0:  # 技能0：火球
                    for _ in range(3):
                        vel = (random.uniform(-2, 2), random.uniform(-2, 2))
                        self.particles.append(Particle(current_x, current_y, RED, vel, 20))
                elif self.skill_type == 1:  # 技能1：闪电
                    for _ in range(2):
                        vel = (random.uniform(-3, 3), random.uniform(-3, 3))
                        self.particles.append(Particle(current_x, current_y, YELLOW, vel, 15))
                elif self.skill_type == 2:  # 技能2：冰块
                    for _ in range(2):
                        vel = (random.uniform(-1, 1), random.uniform(-1, 1))
                        self.particles.append(Particle(current_x, current_y, LIGHT_BLUE, vel, 25))
                
                if self.progress >= 1.0:
                    self.finished = True
                    # 击中特效
                    for _ in range(20):
                        vel = (random.uniform(-5, 5), random.uniform(-5, 5))
                        color = [RED, YELLOW, ORANGE][self.skill_type % 3]
                        self.particles.append(Particle(self.end_pos[0], self.end_pos[1], color, vel, 30))
            
            # 更新粒子
            self.particles = [p for p in self.particles if p.life_time > 0]
            for particle in self.particles:
                particle.update()
        
        def draw(self, screen):
            # 绘制技能轨迹
            if not self.finished:
                current_x = self.start_pos[0] + (self.end_pos[0] - self.start_pos[0]) * self.progress
                current_y = self.start_pos[1] + (self.end_pos[1] - self.start_pos[1]) * self.progress
                
                # 技能图标
                colors = [RED, YELLOW, LIGHT_BLUE]
                pygame.draw.circle(screen, colors[self.skill_type % 3], (int(current_x), int(current_y)), 10)
            
            # 绘制粒子
            for particle in self.particles:
                particle.draw(screen)

    class BossVisualization:
        def __init__(self, data: Dict):
            self.data = data
            self.bosses = data["B"][:]
            self.original_bosses = data["B"][:]
            self.skills = data["PlayerSkills"]
            self.current_boss = 0
            self.turn = 0
            self.cooldowns = [0] * len(self.skills)
            
            # 可视化状态
            self.effects = []
            self.game_state = "playing"  # playing, victory, game_over
            self.auto_play = False
            self.auto_actions = []
            self.auto_action_index = 0
            self.auto_delay = 0
            
            # BOSS死亡延迟机制
            self.pending_deaths = []  # 存储应该在特效完成后死亡的BOSS索引
            
            # 位置设置
            self.player_pos = (150, 400)
            self.boss_positions = [
                (800, 200), (1000, 200),
                (800, 400), (1000, 400)
            ]
            
            # 计算最优解
            result = boss_battle_optimization(data)
            self.optimal_actions = result["actions"]
            self.optimal_turns = result["min_turns"]
            
            # 自动开始播放最优解
            self.start_auto_play()
            
        def get_current_boss_pos(self):
            if self.current_boss < len(self.boss_positions):
                return self.boss_positions[self.current_boss]
            return (900, 300)
        
        def use_skill(self, skill_idx: int):
            """使用技能"""
            if self.game_state != "playing":
                return False
            
            if self.cooldowns[skill_idx] > 0:
                return False
            
            # 检查当前BOSS是否还活着
            if self.current_boss >= len(self.bosses) or self.bosses[self.current_boss] <= 0:
                return False
            
            # 创建技能特效
            effect = SkillEffect(self.player_pos, self.get_current_boss_pos(), skill_idx, self.skills[skill_idx][0])
            self.effects.append(effect)
            
            # 应用技能效果
            damage, cooldown_time = self.skills[skill_idx]
            self.bosses[self.current_boss] -= damage
            
            # 检查boss是否应该死亡，但不立即改变状态
            if self.bosses[self.current_boss] <= 0:
                # 将死亡的BOSS加入延迟处理列表
                if self.current_boss not in self.pending_deaths:
                    self.pending_deaths.append(self.current_boss)
            
            # 更新冷却
            self.cooldowns = [max(0, cd - 1) for cd in self.cooldowns]
            self.cooldowns[skill_idx] = cooldown_time
            self.turn += 1
            
            return True
        
        def start_auto_play(self):
            """开始自动播放最优解"""
            self.auto_play = True
            self.auto_actions = self.optimal_actions[:]
            self.auto_action_index = 0
            self.auto_delay = 0
            
            # 重置游戏状态
            self.bosses = self.original_bosses[:]
            self.current_boss = 0
            self.turn = 0
            self.cooldowns = [0] * len(self.skills)
            self.game_state = "playing"
            self.effects = []
            self.pending_deaths = []
        
        def update(self):
            """更新游戏状态"""
            # 更新特效
            old_effects_count = len(self.effects)
            self.effects = [effect for effect in self.effects if not (effect.finished and not effect.particles)]
            for effect in self.effects:
                effect.update()
            
            # 检查是否有特效刚刚完成
            if len(self.effects) < old_effects_count and self.pending_deaths:
                # 处理延迟的BOSS死亡
                for boss_idx in self.pending_deaths:
                    if boss_idx == self.current_boss:
                        self.current_boss += 1
                self.pending_deaths.clear()
                
                # 检查游戏是否结束
                if self.current_boss >= len(self.bosses):
                    self.game_state = "victory"
            
            # 自动播放逻辑
            if self.auto_play and self.game_state == "playing":
                self.auto_delay += 1
                if self.auto_delay >= 60:  # 1秒延迟
                    # 检查是否还有未击败的BOSS
                    if self.current_boss >= len(self.bosses):
                        self.auto_play = False
                        return
                    
                    # 检查当前BOSS是否还活着（考虑pending死亡）
                    if (self.bosses[self.current_boss] <= 0 and 
                        self.current_boss not in self.pending_deaths):
                        # 当前BOSS已死，寻找下一个活着的BOSS
                        while (self.current_boss < len(self.bosses) and 
                               self.bosses[self.current_boss] <= 0 and
                               self.current_boss not in self.pending_deaths):
                            self.current_boss += 1
                        
                        if self.current_boss >= len(self.bosses):
                            self.game_state = "victory"
                            self.auto_play = False
                            return
                    
                    # 执行下一个动作
                    if self.auto_action_index < len(self.auto_actions):
                        skill_idx = self.auto_actions[self.auto_action_index]
                        if self.use_skill(skill_idx):
                            self.auto_action_index += 1
                            self.auto_delay = 0
                    else:
                        self.auto_play = False
        
        def draw_boss(self, screen, boss_idx: int):
            """绘制BOSS"""
            if boss_idx >= len(self.bosses):
                return
            
            pos = self.boss_positions[boss_idx] if boss_idx < len(self.boss_positions) else (900, 300)
            
            # BOSS外观
            if boss_idx == self.current_boss and (self.bosses[boss_idx] > 0 or boss_idx in self.pending_deaths):
                # 当前BOSS - 红色高亮
                color = RED
            elif self.bosses[boss_idx] <= 0 and boss_idx not in self.pending_deaths:
                # 已死亡BOSS（特效已完成）
                color = DARK_GRAY
            else:
                # 未激活BOSS - 使用不同的彩色
                colors = [BLUE, GREEN, PURPLE, ORANGE, YELLOW, LIGHT_BLUE]
                color = colors[boss_idx % len(colors)]
            
            # 绘制BOSS主体
            pygame.draw.circle(screen, color, pos, 50)
            pygame.draw.circle(screen, BLACK, pos, 50, 3)
            
            # BOSS编号
            boss_text = font_medium.render(f"BOSS{boss_idx}", True, WHITE)
            text_rect = boss_text.get_rect(center=(pos[0], pos[1] - 20))
            screen.blit(boss_text, text_rect)
            
            # 血量条
            if self.bosses[boss_idx] > 0 or boss_idx in self.pending_deaths:
                bar_width = 80
                bar_height = 10
                bar_x = pos[0] - bar_width // 2
                bar_y = pos[1] + 60
                
                # 血量条背景
                pygame.draw.rect(screen, DARK_GRAY, (bar_x, bar_y, bar_width, bar_height))
                
                # 血量条前景
                hp_ratio = max(0, self.bosses[boss_idx]) / self.original_bosses[boss_idx]
                hp_width = int(bar_width * hp_ratio)
                health_color = GREEN if hp_ratio > 0.5 else YELLOW if hp_ratio > 0.2 else RED
                pygame.draw.rect(screen, health_color, (bar_x, bar_y, hp_width, bar_height))
                
                # 血量文字
                displayed_hp = max(0, self.bosses[boss_idx])
                hp_text = font_small.render(f"{displayed_hp}/{self.original_bosses[boss_idx]}", True, WHITE)
                hp_rect = hp_text.get_rect(center=(pos[0], bar_y + bar_height + 15))
                screen.blit(hp_text, hp_rect)
        
        def draw_player(self, screen):
            """绘制玩家"""
            # 玩家主体
            pygame.draw.circle(screen, BLUE, self.player_pos, 30)
            pygame.draw.circle(screen, WHITE, self.player_pos, 30, 3)
            
            # 玩家标签
            player_text = font_medium.render("Player", True, WHITE)
            text_rect = player_text.get_rect(center=(self.player_pos[0], self.player_pos[1] - 50))
            screen.blit(player_text, text_rect)
        
        def draw_skills(self, screen):
            """绘制技能界面"""
            skill_area_y = SCREEN_HEIGHT - 150
            skill_width = 180
            skill_height = 100
            
            for i, (damage, cooldown_time) in enumerate(self.skills):
                x = 50 + i * (skill_width + 20)
                y = skill_area_y
                
                # 技能按钮背景
                if self.cooldowns[i] > 0:
                    color = DARK_GRAY
                    border_color = GRAY
                else:
                    color = [PURPLE, ORANGE, LIGHT_BLUE][i % 3]
                    border_color = WHITE
                
                pygame.draw.rect(screen, color, (x, y, skill_width, skill_height))
                pygame.draw.rect(screen, border_color, (x, y, skill_width, skill_height), 3)
                
                # 技能信息
                skill_text = font_medium.render(f"Skill{i}", True, WHITE)
                damage_text = font_small.render(f"Damage: {damage}", True, WHITE)
                cooldown_text = font_small.render(f"Cooldown: {cooldown_time}", True, WHITE)
                
                screen.blit(skill_text, (x + 10, y + 10))
                screen.blit(damage_text, (x + 10, y + 40))
                screen.blit(cooldown_text, (x + 10, y + 65))
                
                # 冷却时间显示
                if self.cooldowns[i] > 0:
                    cd_text = font_large.render(str(self.cooldowns[i]), True, RED)
                    cd_rect = cd_text.get_rect(center=(x + skill_width//2, y + skill_height//2))
                    screen.blit(cd_text, cd_rect)
        
        def draw_ui(self, screen):
            """绘制UI信息"""
            # 回合数
            turn_text = font_large.render(f"Turn: {self.turn}", True, WHITE)
            screen.blit(turn_text, (20, 20))
            
            # 最优解信息
            optimal_text = font_medium.render(f"Optimal: {self.optimal_turns} turns", True, GOLD)
            screen.blit(optimal_text, (20, 70))
            
            # 当前BOSS提示
            if self.current_boss < len(self.bosses):
                boss_text = font_medium.render(f"Target: BOSS{self.current_boss}", True, WHITE)
                screen.blit(boss_text, (20, 110))
            
            # 按键提示
            if not self.auto_play:
                help_text = [
                    "Controls:",
                    "1,2,3 - Use skills",
                    "SPACE - Auto play",
                    "R - Reset game"
                ]
                for i, text in enumerate(help_text):
                    color = YELLOW if i == 0 else WHITE
                    help_surface = font_small.render(text, True, color)
                    screen.blit(help_surface, (SCREEN_WIDTH - 200, 20 + i * 25))
        
        def draw_victory(self, screen):
            """绘制胜利画面"""
            # 半透明覆盖
            overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
            overlay.set_alpha(180)
            overlay.fill(BLACK)
            screen.blit(overlay, (0, 0))
            
            # 胜利文字
            victory_text = font_large.render("VICTORY!", True, GOLD)
            victory_rect = victory_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 - 50))
            screen.blit(victory_text, victory_rect)
            
            # 统计信息
            stats_text = [
                f"Your time: {self.turn} turns",
                f"Optimal: {self.optimal_turns} turns",
                f"Efficiency: {self.optimal_turns}/{self.turn} = {self.optimal_turns/max(self.turn,1):.2%}"
            ]
            
            for i, text in enumerate(stats_text):
                color = GREEN if "Efficiency" not in text else (GREEN if self.turn <= self.optimal_turns else YELLOW)
                stats_surface = font_medium.render(text, True, color)
                stats_rect = stats_surface.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + i * 40))
                screen.blit(stats_surface, stats_rect)
            
            # 重新开始提示
            restart_text = font_small.render("Press R to restart", True, WHITE)
            restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 150))
            screen.blit(restart_text, restart_rect)
        
        def draw(self, screen):
            """绘制所有内容"""
            screen.fill(BLACK)
            
            # 绘制背景
            pygame.draw.rect(screen, DARK_GRAY, (0, SCREEN_HEIGHT - 170, SCREEN_WIDTH, 170))
            
            # 绘制游戏元素
            self.draw_player(screen)
            
            for i in range(len(self.original_bosses)):
                self.draw_boss(screen, i)
            
            # 绘制特效
            for effect in self.effects:
                effect.draw(screen)
            
            # 绘制UI
            self.draw_skills(screen)
            self.draw_ui(screen)
            
            # 绘制胜利画面
            if self.game_state == "victory":
                self.draw_victory(screen)
        
        def handle_event(self, event):
            """处理事件"""
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_1:
                    self.use_skill(0)
                elif event.key == pygame.K_2 and len(self.skills) > 1:
                    self.use_skill(1)
                elif event.key == pygame.K_3 and len(self.skills) > 2:
                    self.use_skill(2)
                elif event.key == pygame.K_SPACE:
                    self.start_auto_play()
                elif event.key == pygame.K_r:
                    # 重置游戏
                    self.bosses = self.original_bosses[:]
                    self.current_boss = 0
                    self.turn = 0
                    self.cooldowns = [0] * len(self.skills)
                    self.game_state = "playing"
                    self.effects = []
                    self.pending_deaths = []
                    self.auto_play = False

    def run_visualization(data):
        """运行可视化模式"""
        screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("Boss Battle Visualization")
        
        # 创建可视化实例
        game = BossVisualization(data)
        
        # 游戏循环
        clock = pygame.time.Clock()
        running = True
        
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                else:
                    game.handle_event(event)
            
            # 更新游戏状态
            game.update()
            
            # 绘制
            game.draw(screen)
            pygame.display.flip()
            
            # 控制帧率
            clock.tick(60)
        
        pygame.quit()

def console_main(json_path):
    # 输入数据
    # data = {"B": [11, 13, 8, 17], "PlayerSkills": [[6, 2], [2, 0], [4, 1]]}
    with open(json_path, 'r') as f:
        data = json.load(f)
    
    print("输入数据：")
    print(f"BOSS血量: {data['B']}")
    print("玩家技能:")
    for i, (damage, cooldown) in enumerate(data["PlayerSkills"]):
        print(f"  技能{i}: 伤害{damage}, 冷却{cooldown}回合")
    
    # 运行优化算法
    result = boss_battle_optimization(data)
    
    print(f"\n优化结果：")
    print(f"最小回合数: {result['min_turns']}")
    print(f"动作序列: {result['actions']}")
    
    # 验证结果
    print(f"\n验证过程：")
    verify_solution(data, result['actions'])
    
    print(f"\n优化结果：")
    print(f"最小回合数: {result['min_turns']}")
    print(f"动作序列: {result['actions']}")
    

def verify_solution(data: Dict, actions: List[int]):
    """验证解的正确性"""
    bosses = data["B"][:]  # 复制BOSS血量
    skills = data["PlayerSkills"]
    cooldowns = [0] * len(skills)
    current_boss = 0
    
    print(f"初始状态: BOSS{current_boss}血量{bosses[current_boss]}")
    
    for turn, skill_idx in enumerate(actions):
        # 检查技能是否可用
        if cooldowns[skill_idx] > 0:
            print(f"错误：第{turn+1}回合技能{skill_idx}仍在冷却")
            return False
        
        # 使用技能
        damage, cooldown_time = skills[skill_idx]
        bosses[current_boss] -= damage
        
        print(f"第{turn+1}回合: 使用技能{skill_idx}(伤害{damage}), BOSS{current_boss}血量: {bosses[current_boss]}")
        
        # 检查BOSS是否被击败
        if bosses[current_boss] <= 0:
            print(f"  -> BOSS{current_boss}被击败！")
            current_boss += 1
            if current_boss >= len(bosses):
                print("所有BOSS都被击败！")
                break
            else:
                print(f"  -> 开始攻击BOSS{current_boss}(血量{bosses[current_boss]})")
        
        # 更新冷却状态
        cooldowns = [max(0, cd - 1) for cd in cooldowns]
        cooldowns[skill_idx] = cooldown_time
        
        if any(cd > 0 for cd in cooldowns):
            cooling_skills = [f"技能{i}({cd})" for i, cd in enumerate(cooldowns) if cd > 0]
            print(f"  -> 冷却中: {', '.join(cooling_skills)}")
    
    return current_boss >= len(bosses)

def main():
    """主函数：支持可视化和控制台模式"""
    json_path = "D:/maze_0701_final/maze_algo-main/算法课设/样例/BOSS战样例/boss_case_1.json"
    
    # 检查命令行参数
    if len(sys.argv) > 1:
        if sys.argv[1] == "--console" or sys.argv[1] == "-c":
            # 强制使用控制台模式
            console_main(json_path)
            return
        elif sys.argv[1] == "--visual" or sys.argv[1] == "-v":
            # 强制使用可视化模式
            if PYGAME_AVAILABLE:
                with open(json_path, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                run_visualization(data)
            else:
                print("pygame未安装，无法使用可视化模式！")
            return
    
    # 交互式选择模式
    print("Boss Battle Algorithm Demo")
    print("="*50)
    
    # 加载数据并显示基本信息
    with open(json_path, 'r', encoding='utf-8') as f:
        data = json.load(f)
    
    print(f"Test case: {json_path}")
    print(f"Boss HP: {data['B']}")
    print("Player skills:")
    for i, (damage, cooldown) in enumerate(data["PlayerSkills"]):
        print(f"  Skill{i}: Damage {damage}, Cooldown {cooldown} turns")
    
    # 计算最优解
    result = boss_battle_optimization(data)
    print(f"\nAlgorithm result: {result['min_turns']} turns")
    print(f"Optimal strategy: {result['actions']}")
    
    print("\nSelect mode:")
    print("1. Visualization mode (Recommended)")
    print("2. Console mode")
    
    if not PYGAME_AVAILABLE:
        print("Note: pygame not installed, console mode only")
        choice = "2"
    else:
        choice = input("Enter choice (1/2) [default 1]: ").strip()
        if not choice:
            choice = "1"
    
    if choice == "1" and PYGAME_AVAILABLE:
        print("\nStarting visualization mode...")
        print("Controls:")
        print("- Press 1,2,3 to use skills")
        print("- Press SPACE to auto play optimal solution") 
        print("- Press R to reset game")
        print("- Close window to exit")
        run_visualization(data)
    else:
        print("\nRunning console mode:")
        console_main(json_path)

if __name__ == "__main__":
    main()
